Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix inconsistent CanvasModulate color in 2D HDR #93802

Conversation

feiyue-z
Copy link
Contributor

@feiyue-z feiyue-z commented Jul 1, 2024

Linearize CanvasModulate color if HDR 2D is on.

Fix #92796

@feiyue-z feiyue-z requested a review from a team as a code owner July 1, 2024 08:13
@Mickeon Mickeon modified the milestones: 4.x, 4.3 Jul 1, 2024
clayjohn
clayjohn previously approved these changes Jul 19, 2024
Copy link
Member

@clayjohn clayjohn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great! Thank you!

Copy link
Member

@Calinou Calinou left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested locally, it works as expected when the root viewport has HDR 2D enabled. However, when the root viewport has HDR 2D disabled, this makes CanvasModulate in SubViewports no longer match each other depending on whether they have HDR 2D enabled.

The SubViewport on the left has HDR 2D disabled, while the one on the right has HDR 2D enabled. Using Forward+.

Testing project: test_pr_93802.zip

HDR 2D enabled on the root Viewport (working correctly in this PR)

Before After
Before After

HDR 2D disabled on the root Viewport (not working correctly in this PR)

Before After
Before After

@feiyue-z
Copy link
Contributor Author

@Calinou
Thank you for the feedback!
I have fixed the issue by adding a check to see if 2D HDR is enabled in project settings. I also took out the linearization in compatibility mode because it seems to work just fine without it.

state_buffer.canvas_modulate[1] = p_modulate.g;
state_buffer.canvas_modulate[2] = p_modulate.b;
state_buffer.canvas_modulate[3] = p_modulate.a;
bool use_linear_colors = texture_storage->render_target_is_using_hdr(p_to_render_target) && GLOBAL_GET("rendering/viewport/hdr_2d");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The project setting should likely be checked in the constructor only once, and saved in a member variable, for performance reasons. Reading project settings for each render command is going to be expensive.

That being said I'm not sure this is the correct check. I haven't looked in depth but I believe rendering/viewport/hdr_2d only sets the default value for the root viewport. It can still be changed later on for any viewport with RenderingServer::viewport_set_use_hdr_2d and Viewport::set_use_hdr_2d.

I'm no rendering expert so TIWAGOS1, but it sounds to me like this might need to check the value for the target viewport. No idea how that's done at this stage of the render pipeline, @clayjohn might know.

Footnotes

  1. Take It With A Grain Of Salt

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suspect the original fix was correct. Taking a look now.

It seems like the demo project is treating the linear HDR Viewport's texture as if it is sRGB color texture. If so, that would be the source of the problem.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ya, the problem comes from the demo project. When HDR_2D is disabled on the root viewport, the root viewport expects to receive sRGB textures (it doesn't do any color conversion). However, the demo passes a linear HD texture which ends up looking incorrect. Simply doing the linear->sRGB conversion in the shader makes the output correct.

This issue highlights a broader issue which is that mixing HDR_2D and non HDR content is still confusing for users and prone to error. So there is likely stuff we can do to improve the situation.

As for this PR, we should not be checking the project setting, the code should be reverted back to the way it was

@akien-mga akien-mga force-pushed the Fix-inconsistent-CanvasModulate-color-in-2D-HDR branch from 181a4db to 6f30df4 Compare July 24, 2024 07:50
Copy link
Member

@akien-mga akien-mga left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I rebased to remove the reverted commits.

Approving on the basis on Clay's original approval, which was later confirmed in discussion.

@akien-mga akien-mga merged commit 27daf3b into godotengine:master Jul 24, 2024
17 checks passed
@akien-mga
Copy link
Member

Thanks! And congrats for your first merged Godot contribution 🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

CanvasModulate color too bright when using 2D HDR
5 participants